﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Windows.Forms;
using System.Diagnostics;
using System.Drawing.Drawing2D;
using System.Drawing;


namespace YDSOO.Windows.Forms.Utils
{
    /// <summary>
    /// WinForm开发的辅助类，主要是一些列表、树、菜单对象的填充方法。
    /// </summary>
    [Serializable]
    public class WinHelper:YDMarshalByRefObject
    {
        /// <summary>
        /// 使用数据表填充树控件
        /// </summary>
        /// <remarks>采用2个字典，只需遍历一次即可生成，安义</remarks>
        /// <param name="tv">树控件</param>
        /// <param name="datasource">数据表，可以不排序</param>
        /// <param name="key">键名称</param>
        /// <param name="parentkey">父键名称</param>
        /// <param name="display">显示列</param>
        /// <param name="imageindex">图像索引列</param>
        /// <param name="expand">是否展开</param>
        /// <exception cref="IndexOutOfRangeException">字典错误会导致异常抛出</exception>
        /// <returns>是否成功</returns>
        public static bool BuildTree(TreeView tv, DataTable datasource, string key, string parentkey, string display, string imageindex, bool expand)
        {
            Trace.Assert(tv != null);
            Trace.Assert(datasource != null);
            Trace.Assert(!String.IsNullOrEmpty(key));
            Trace.Assert(!String.IsNullOrEmpty(parentkey));
            Trace.Assert(!String.IsNullOrEmpty(display));

            if (datasource == null || String.IsNullOrEmpty(key) || String.IsNullOrEmpty(parentkey))
                return false;

            //每个节点放这里
            Dictionary<string, TreeNode> dtree = new Dictionary<string, TreeNode>();

            //找不到根的节点放这里
            Dictionary<string, string> dleft = new Dictionary<string, string>();

            foreach (DataRow dr in datasource.Rows)
            {
                TreeNode tn = new TreeNode(dr[display].ToString());
                tn.Tag = dr;
                if (!String.IsNullOrEmpty(imageindex))
                    tn.ImageIndex = Convert.ToInt16(dr[imageindex]);
                dtree.Add(dr[key].ToString(), tn);

                //确定根节点
                if (dr[key].ToString() == dr[parentkey].ToString() || dr[parentkey].ToString() == "0" || String.IsNullOrEmpty(dr[parentkey].ToString()))
                {
                    tv.Nodes.Add(tn);
                    continue;
                }
                if (dtree.ContainsKey(dr[parentkey].ToString()))
                {
                    TreeNode tmpNode = dtree[dr[parentkey].ToString()];
                    if (tmpNode != null)
                        tmpNode.Nodes.Add(tn);
                    else
                        throw new ArgumentOutOfRangeException("数据字典损坏");
                }
                else
                    dleft.Add(dr[parentkey].ToString(), dr[key].ToString());

                //反向查询，即再判断一下，新加的这个节点是否是某个抛弃的节点的父节点
                //用这种方式是因为每次只增加一个节点，不会出现多余的
                if (dleft.ContainsKey(dr[key].ToString()))
                {
                    //取出这个id
                    string id = dleft[dr[key].ToString()];
                    //从第一表中取出节点
                    TreeNode tmpNode = dtree[id];
                    //将取出的节点加到当前节点上
                    tn.Nodes.Add(tmpNode);
                    //移除本节点
                    dleft.Remove(dr[key].ToString());
                }
            }
            //最后剩下的节点是无根的节点，放在根目录上
            //
            foreach (string pid in dleft.Keys)
            {
                string id = "";
                dleft.TryGetValue(pid, out id);
                TreeNode tmpNode = dtree[id];
                tv.Nodes.Add(tmpNode);
            }
            tv.Tag = dtree;
            if (expand)
                tv.ExpandAll();
            return true;
        }
    }

    public static class FormDecorator
    {
        public static void SetWindowRegion(Form frm)
        {
            GraphicsPath FormPath;
            FormPath = new GraphicsPath();
            Rectangle rect = new Rectangle(0, 0, frm.Width, frm.Height);//this.Left-10,this.Top-10,this.Width-10,this.Height-10);                 

            FormPath = GetRoundedRectPath(rect, 10);
            frm.Region = new Region(FormPath);
        }
        private static  GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
        {
            int diameter = radius;
            Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
            GraphicsPath path = new GraphicsPath();
            //   左上角      
            path.AddArc(arcRect, 180, 90);
            //   右上角   
            arcRect.X = rect.Right - diameter;
            path.AddArc(arcRect, 270, 90);
            //   右下角    
            arcRect.Y = rect.Bottom - diameter;
            path.AddArc(arcRect, 0, 90);
            //   左下角      
            arcRect.X = rect.Left;
            path.AddArc(arcRect, 90, 90);
            path.CloseFigure();
            return path;
        }
    }
}
